﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Text.RegularExpressions;

namespace DisplayBoardInfoClient
{
    /// <summary>
    /// Okno aplikacji wyświetlane dla osób pracujących w rejestracji.
    /// </summary>
    public partial class ReceptionWindow : Window
    {
        //private SortedList<string, PatientVisit> entries;
        /// <summary>
        /// Lista pokoi pobrana z serwera.
        /// </summary>
        private SortedList<string, Room> roomList = new SortedList<string,Room>();
        /// <summary>
        /// Data wybrana w kalendarzu.
        /// </summary>
        private DateTime dateChoosen;
        /// <summary>
        /// Tworzy obiekt klasy, pobiera z serwera listę pacjentów i pokoi. Pobiera listę wizyt na obecny dzień i rozpoczyna wyświetlanie.
        /// </summary>
        public ReceptionWindow()
        {
            InitializeComponent();
            calendarChoose.SelectedDate = DateTime.Today;
            dateChoosen = DateTime.Today;
            //entries = new SortedList<string, PatientVisit>();
            //entries.Add("08:15", new PatientVisit(new DateTime(DateTime.Today.Year, DateTime.Today.Month, DateTime.Today.Day, 8, 15, 0, DateTimeKind.Local), "Michał", "Masztalski", "88060501202",15));
            //PatientList.addPatient(new PatientList.Patient("Michał", "Masztalski", "88060501202"));
            XMLConfiguration.init(Constants.CONF_FILE_PATH);
            ServerClient.getPatientList();
            List<Room> listapokoi = ServerClient.getRoomList();
            foreach (Room r in listapokoi)
            {
                roomList.Add(r.Number, r);
                roomCombo.Items.Add(r.Number);
            }
            if (roomList.Count > 0)
            {
                roomCombo.SelectedIndex = 0;
                roomComboChanged(new Object(), null);
                calendarChoose_SelectedDatesChanged(calendarChoose, null);
            }
            refreshVisitBox();
        }
        /// <summary>
        /// Resetuje zawartość pola tekstowego, które zgłosiło zdarzenie na pusty.
        /// </summary>
        /// <param name="sender">obiekt zgłaszający zdarzenie</param>
        /// <param name="e">dodatkowe paramery zdarzenia</param>
        private void resetTextBox(object sender, EventArgs e)
        {

            if (sender is TextBox)
            {
                if (((TextBox)sender).Text.Equals("HH:mm") || ((TextBox)sender).Text.Equals("Imię") ||
                    ((TextBox)sender).Text.Equals("Nazwisko") || ((TextBox)sender).Text.Equals("PESEL") || ((TextBox)sender).Text.Equals("mm"))
                {
                    ((TextBox)sender).Text = "";
                }
                else
                    return;


            }
        }
        /// <summary>
        /// Dodaje nową wizyty w rezultacie na kliknięcie odpowiedniego przycisku. Weryfikuje wprowadzone dane po czym wysyła żądanie do serwera o potwierdzenie.
        /// </summary>
        /// <param name="sender">obiekt zgłaszający zdarzenie</param>
        /// <param name="e">dodatkowe parametry zdarzenia</param>
        private void addVisitClick(object sender, RoutedEventArgs e)
        {
            if (hourBox.Text.Equals("HH:mm") || surnameBox.Text.Equals("Nazwisko") || nameBox.Text.Equals("Imię") 
                || peselBox.Text.Equals("PESEL"))
            {
                MessageBox.Show("Wszystkie pola muszą zostać wypełnione.");
                return;
            }
            if (roomCombo.Text.Equals(""))
            {
                MessageBox.Show("Wybierz pokój.");
                return;
            }
            Regex hourPattern = new Regex("^[0-2][0-9]:[0-5][0-9]$");
            Regex peselPattern = new Regex("^[0-9]{11}$");
            Regex durationParrest = new Regex("^[0-6][0-9]$");
            if (!hourPattern.IsMatch(hourBox.Text))
            {
                MessageBox.Show("Godzina w niepoprawnym formacie (HH:mm).");
                return;
            }
            if (!peselPattern.IsMatch(peselBox.Text))
            {
                MessageBox.Show("PESEL w niepoprawnym formacie (11 cyfr).");
                return;
            }
            if (!durationParrest.IsMatch(durationBox.Text))
            {
                MessageBox.Show("Czas trwania w niepoprawnym formacie (mm).");
                return;
            }
            //entries.Add(hourBox.Text, new PatientVisit(new DateTime(dateChoosen.Year, dateChoosen.Month, dateChoosen.Day,
               // Int32.Parse(hourBox.Text.Substring(0, 2)), Int32.Parse(hourBox.Text.Substring(3, 2)), 0, DateTimeKind.Local), 
               // nameBox.Text, surnameBox.Text, peselBox.Text));
            if (PatientList.getPatient(peselBox.Text) == null)
            {
                if (!ServerClient.addPatient(nameBox.Text, surnameBox.Text, peselBox.Text))
                    return;
            }
            if (!ServerClient.addVisit(new PatientVisit(new DateTime(dateChoosen.Year, dateChoosen.Month, dateChoosen.Day,
                Int32.Parse(hourBox.Text.Substring(0, 2)), Int32.Parse(hourBox.Text.Substring(3, 2)), 0, DateTimeKind.Local),
                nameBox.Text, surnameBox.Text, peselBox.Text, Int32.Parse(durationBox.Text), PatientList.getPatient(peselBox.Text).ID), roomList[roomCombo.Text]))
                return;
            hourBox.Text = ("HH:mm");
            nameBox.Text = ("Imię");
            surnameBox.Text = ("Nazwisko");
            peselBox.Text = ("PESEL");
            durationBox.Text = ("mm");
            refreshVisitBox();
        }
        /// <summary>
        /// Odświeża wizyty w list boxie. Pobiera listę wizyt dla danego dnia i pokoju z serwera po czym aktualizuje listę.
        /// </summary>
        private void refreshVisitBox()
        {
            if (calendarChoose.SelectedDate == null)
            {
                MessageBox.Show("Wybierz datę."); return;

            }
            if (!roomCombo.Text.Equals(""))
            {
                ServerClient.getDailyPlan(roomList[roomCombo.Text], (DateTime)(calendarChoose.SelectedDate));
            }
            visitsList.Items.Clear();
            for (int i=0;i<1000;i++)
            {
                PatientVisit visit=DailyPlan.Instance.get(i);
                if (visit == null) break;
                ListBoxItem item = new ListBoxItem();
                item.FontSize = 16;
                item.Content = visit.ToString(PatientVisit.ToStringType.Reception);
                visitsList.Items.Add(item);
            }
            if (!roomCombo.Text.Equals(""))
            {
                foreach (DayOpenList.OpenHours oh in DailyPlan.Instance.getAdmission(calendarChoose.SelectedDate.Value.DayOfWeek).list.Values)
                {
                    openHoursBox.Items.Add(oh.ToString());
                }
            }
        }
        private void roomComboChanged(object sender, SelectionChangedEventArgs e)
        {
            if (!roomCombo.Text.Equals(""))
            {
                ServerClient.getRoomOpening(roomList[roomCombo.Text]);
                refreshVisitBox();
            }

        }
        /// <summary>
        /// Metoda obsługuje zmianę daty w kalendarzu. Powoduje to odświeżenie listy wizyt.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void calendarChoose_SelectedDatesChanged(object sender, SelectionChangedEventArgs e)
        {
            dateChoosen= calendarChoose.SelectedDate != null ? (DateTime) calendarChoose.SelectedDate :  DateTime.Today;
            refreshVisitBox();
            
        }
        /// <summary>
        /// Metoda obsługuje kliknięcie przycisku "Modyfikuj". Pobiera obiekt odpowiedzialny za wybraną wizytę i otwiera okno do edycji wypełnione danymi
        /// z wybranej wizyty. Po wykonaniu modyfikacji odświeża listę wizyt.
        /// </summary>
        /// <param name="sender">obiekt zgłaszający zdarzenie</param>
        /// <param name="e">dodatkowe parametry zdarzenia</param>
        private void modifyButton_Click(object sender, RoutedEventArgs e)
        {
            if (visitsList.SelectedItem == null)
            {
                MessageBox.Show("Wybierz wizytę którą chcesz modyfikować");
                return;
            }
            if (roomCombo.Text.Equals(""))
            {
                MessageBox.Show("Wybierz pokój.");
                return;
            }
            EditWindow eWindow = new EditWindow(DailyPlan.Instance.get(visitsList.SelectedIndex),roomList[roomCombo.Text]);
            eWindow.ShowDialog();
            refreshVisitBox();
        }
        /// <summary>
        /// Obsluguje kliknięcie w guzik "Usuń". Wysyłado serwera polecenie usunięcia wybranej wizyty. Po usunięciu odświeża listę wizyt.
        /// </summary>
        /// <param name="sender">obiekt zgłaszający zdarzenie</param>
        /// <param name="e">dodatkowe parametry zdarzenia</param>
        private void delButton_Click(object sender, RoutedEventArgs e)
        {
            if (visitsList.SelectedItem == null)
            {
                MessageBox.Show("Wybierz wizytę którą chcesz usunąć");
                return;
            }
            if (roomCombo.Text.Equals(""))
            {
                MessageBox.Show("Wybierz pokój.");
                return;
            }
            if (ServerClient.delVisit(DailyPlan.Instance.get(visitsList.SelectedIndex), roomList[roomCombo.Text]))
            {
                refreshVisitBox();
            }
            else
            {
                refreshVisitBox();

            }

        }
        /// <summary>
        /// Przywraca wartości pola tekstowego jego domyślną wartość jeżeli żadna wartość nie została do niego wprowadzona. Domyślna wartość 
        /// zależy od nazwy pola tekstowego.
        /// </summary>
        /// <param name="sender">obiekt zgłaszający zdarzenie</param>
        /// <param name="e">dodatkowe parametry zdarzenia</param>
        private void textBox_LostFocus(object sender, RoutedEventArgs e)
        {
            if (sender is TextBox)
            {
                if (((TextBox)sender).Text.Equals(""))
                {
                    switch (((TextBox)sender).Name)
                    {
                        case "hourBox":
                            {
                                ((TextBox)sender).Text = ("HH:mm");
                                break;
                            }
                        case "nameBox":
                            {
                                ((TextBox)sender).Text = ("Imię");
                                break;
                            }
                        case "peselBox":
                            {
                                ((TextBox)sender).Text = ("PESEL");
                                break;
                            }
                        case "surnameBox":
                            {
                                ((TextBox)sender).Text = ("Nazwisko");
                                break;
                            }
                        case "durationBox":
                            {
                                ((TextBox)sender).Text = ("mm");
                                break;
                            }
                    }
                }
            }
        }
        /// <summary>
        /// Metoda sprawdza listę pacjentów w poszukiwaniu wprowadzonego numeru PESEL. Jeżeli taki pesel już się na niej znajduje,
        /// automatycznie wypełniane są pola imię i nazwisko pacjenta.
        /// </summary>
        /// <param name="sender">obiekt zgłaszający zdarzenie</param>
        /// <param name="e">dodatkowe parametry zdarzenia</param>
        private void PESELBox_LostFocus(object sender, RoutedEventArgs e)
        {
             if (((TextBox)sender).Text.Equals(""))
                 ((TextBox)sender).Text = ("PESEL");
             Regex peselPattern = new Regex("^[0-9]{11}$");
             if (!peselPattern.IsMatch(peselBox.Text))
             {
                 MessageBox.Show("PESEL w niepoprawnym formacie (11 cyfr).");
                 return;
             }
             if (PatientList.getPatient(peselBox.Text)!=null)
             {
                 PatientList.Patient patient = PatientList.getPatient(peselBox.Text);
                 nameBox.Text = patient.Name;
                 surnameBox.Text = patient.Surname;
             }
            
        }


    }
}
